//
//	DockTest.c
//
//	Simple demo of the DockWindow library
//	
//	Copyright J Brown 2001
//	Freeware
//
#include <windows.h>
#include <tchar.h>
#include <commctrl.h>

#include "resource.h"
#include "DockWindow.h"

#pragma comment(lib, "comctl32.lib")

TCHAR szAppName[] = _T("Main Window");

#define MAX_DOCKERS 10

HWND	hwndMain;

DockWnd dwndDocker[MAX_DOCKERS];
int     nNumDockers = 0;

//
//	
//
DWORD dwToolBarStyles =  WS_CHILD | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | 
						 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | 
						CCS_NOPARENTALIGN |  CCS_NORESIZE| CCS_NODIVIDER;


TBBUTTON tbb[] = 
{
	{	STD_FILENEW,	0,	TBSTATE_ENABLED, TBSTYLE_BUTTON,  0,0, 0, 0 },
	{	STD_FILEOPEN,	0,	TBSTATE_ENABLED, TBSTYLE_BUTTON,  0,0, 0, 1 },
	{	STD_FILESAVE,	0,	TBSTATE_ENABLED, TBSTYLE_BUTTON,  0,0, 0, 2 }, 
	{	0,				0,	TBSTATE_ENABLED, TBSTYLE_SEP,	  0,0, 0, 0 },
	{	STD_CUT,		0,				  0, TBSTYLE_BUTTON,  0,0, 0, 3 },
	{	STD_COPY,		0,				  0, TBSTYLE_BUTTON,  0,0, 0, 4 },
	{	STD_PASTE,		0,	TBSTATE_ENABLED, TBSTYLE_BUTTON,  0,0, 0, 5 },
	{	0,				0,	TBSTATE_ENABLED, TBSTYLE_SEP,	  0,0, 0, 0 },
	{	STD_UNDO,		0,				  0, TBSTYLE_BUTTON,  0,0, 0, 6 },
	{	STD_REDOW,		0,				  0, TBSTYLE_BUTTON,  0,0, 0, 7 },
	{	STD_FIND,		0,	TBSTATE_ENABLED, TBSTYLE_BUTTON,  0,0, 0, 8 },
};

char szTBStrings[] = "New\0Open\0Save\0Cut\0Paste\0Copy\0Undo\0Redo\0Find\0\0";

HWND CreateTB(HWND hwndParent)
{
	RECT r;
	int iNumButtons;
	HWND hwndTB;

	iNumButtons = 12;

	hwndTB = CreateToolbarEx (hwndParent,
			dwToolBarStyles,
			1, iNumButtons,
			HINST_COMMCTRL,
			IDB_STD_SMALL_COLOR,
			tbb,
			iNumButtons,
			55, 36, 36, 36,
			sizeof(TBBUTTON) );

	//	calculate toolbar height
	GetWindowRect(hwndTB, &r);
	
	//Add the strings to the toolbar
	SendMessage(hwndTB, TB_ADDSTRING, 0, (LPARAM)szTBStrings);
	SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON),0);
	SendMessage(hwndTB, TB_AUTOSIZE, 0, 0);

	SetWindowText(hwndTB, _T("Toolbar"));

	return hwndTB;
}

//
//	Create one of three types of window
//
HWND CreateRandomWindow(HWND hwndParent)
{
	if(nNumDockers >= MAX_DOCKERS)
		return 0;

	nNumDockers++;

	switch(rand() % 3)
	{
	case 0:
		return CreateWindowEx(WS_EX_CLIENTEDGE, 
			"EDIT", "Contents", 
			ES_MULTILINE|WS_VSCROLL|WS_CHILD|WS_VISIBLE,
			0,0,400,64,
			hwndParent,
			0,GetModuleHandle(0),0);

	case 1:
		return CreateWindowEx(WS_EX_CLIENTEDGE, 
			WC_TREEVIEW, "Tree", 
			WS_VSCROLL|WS_CHILD|WS_VISIBLE,
			0,0,400,64,
			hwndParent,
			0,GetModuleHandle(0),0);

	case 2:
		return CreateTB(hwndParent);
	}

	return 0;
}


// Can't remember why I wrote this func...!
void PaintWndRect(HDC hdc, RECT *rc, HBRUSH hbr)
{
	HWND hwnd = WindowFromDC(hdc);
	RECT r = *rc;
	RECT g;
	GetWindowRect(hwnd, &g);
	OffsetRect(&r, -g.left, -g.top);
	FillRect(hdc, &r, hbr);
}

//
//	Window procedure for main window
//
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int x = 200, y = 200;
	static int count = 1;

	int i;
	TCHAR szName[32];
	NMHDR *hdr;

	int width, height;
	RECT rect;
	HDWP hdwp;

	switch(msg)
	{
	case WM_CREATE:
		ZeroMemory(&dwndDocker, sizeof(dwndDocker));

		for(i = 0; i < MAX_DOCKERS; i++)
		{
			dwndDocker[i].cxFloating = 400;
			dwndDocker[i].cyFloating = 64;
			dwndDocker[i].xpos = 200+i*10;
			dwndDocker[i].ypos = 200+i*10;
			dwndDocker[i].uDockedState = DWS_DOCKED_TOP;
		}

		return 0;

	case WM_NCACTIVATE:
		return HANDLE_NCACTIVATE(hwnd, hwnd, wParam, lParam);

	case WM_ENABLE:
		return HANDLE_ENABLE(hwnd, hwnd, wParam, lParam);

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_CLOSE:
		DestroyWindow(hwnd);
		return 0;

	// position any DOCKED toolwindows - 
	case WM_SIZE:
		width  = LOWORD(lParam);
		height = HIWORD(lParam);

		// Work out where dock windows are allowed
		// (Take into account status bar, toolbar etc)
		SetRect(&rect, 0, 0, width, height);
		
		hdwp = BeginDeferWindowPos(nNumDockers);

		// Position the specified dock windows. rect will be modified to contain the
		// "inner" client rectangle, where we can position an MDI client,
		// view window, whatever
		DockWnd_Position(hwnd, hdwp, dwndDocker, nNumDockers, &rect);

		EndDeferWindowPos(hdwp);

		// MoveWindow(hwndView, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
		return 0;

	case WM_NOTIFY:
		hdr = (NMHDR *)lParam;
		
		if(hdr->code == DWN_ISDOCKABLE)
		{
			RECT rc1, rc2;

			// Get main window "outer" rectangle
			GetWindowRect(hwnd, &rc1);
	
			// Get main window "inner" rectangle
			GetClientRect(hwnd, &rc2);
			MapWindowPoints(hwnd, 0, (POINT *)&rc2, 2);
			InflateRect(&rc2, -2, -2);

			return DockWnd_GetDockSide(hwnd, (NMDOCKWNDQUERY *)lParam, &rc1, &rc2);
		}

		break;


	case WM_COMMAND:

		switch(LOWORD(wParam))
		{
		case IDM_HELP_ABOUT:
			MessageBox(hwnd, "Look how all the popups go inactive", szAppName, MB_OK);
			return 0;

		case IDM_FILE_NEW:
			
			if(nNumDockers < MAX_DOCKERS)
			{
				HWND hwndNew = CreateRandomWindow(hwnd);

				if(hwndNew != 0)
				{
					// Set the contents to the new window
					dwndDocker[nNumDockers-1].hwndContents = hwndNew;

					// Set the borders
					SetRect(&dwndDocker[nNumDockers-1].rcBorderDock, 4, 3, 3, 3);
					SetRect(&dwndDocker[nNumDockers-1].rcBorderFloat, 4, 3, 3, 3);

					// Docking styles
					dwndDocker[nNumDockers-1].dwStyle = 
						DWS_USEBORDERS | 
						DWS_DRAWGRIPPERDOCKED | 
						DWS_DRAWGRIPPERFLOATING|
						DWS_BORDERTOP|
						DWS_BORDERBOTTOM;

					// prevent sizing..
					//dwndDocker[nNumDockers-1].dwStyle |= DWS_NORESIZE;

					// Set the window title
					wsprintf(szName, "Tool Window %d", count++);
					
					// Create a docking window!
					CreateDockWnd(&dwndDocker[nNumDockers-1], hwnd, szName);

					// Adjust coords for next time a window is created
					x += 10;
					y += 10;

					if(x > 800 || y > 600)
					{
						x = 0;
						y = 0;
					}
				}
			}

			return 0;

		case IDM_FILE_DOCK:
			DockWnd_ToggleDockingMode(dwndDocker[nNumDockers-1].hwnd);
			return 0;
		}

		return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}

HWND CreateMainWnd(HWND hwndParent)
{
	HWND hwnd;
	
	hwnd = CreateWindowEx(
				0,
				szAppName,				// window class name
				szAppName,				// window caption
				WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
				CW_USEDEFAULT,			// initial x position
				CW_USEDEFAULT,			// initial y position
				650,					// initial x size
				320,					// initial y size
				NULL,					// parent window handle
				NULL,					// use window class menu
				GetModuleHandle(0),		// program instance handle
				NULL);					// creation parameters

	return hwnd;
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int iShowCmd)
{
	MSG			msg;
	WNDCLASSEX	wc;
	HACCEL		hAccelTable;
	
	INITCOMMONCONTROLSEX ice;

	ice.dwSize = sizeof(ice);
	ice.dwICC  = ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES;
	InitCommonControlsEx(&ice);

	ZeroMemory(&wc, sizeof(wc));

	//Window class for the main application parent window
	wc.cbSize			= sizeof(wc);
	wc.style			= 0;
	wc.lpfnWndProc		= WndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hInst;
	wc.hIcon			= LoadIcon(0, MAKEINTRESOURCE(IDI_APPLICATION));
	wc.hCursor			= LoadCursor (NULL, IDC_ARROW);
	wc.hbrBackground	= (HBRUSH)(COLOR_APPWORKSPACE+1);
	wc.lpszMenuName		= MAKEINTRESOURCE(IDR_MENU1);
	wc.lpszClassName	= szAppName;
	wc.hIconSm			= LoadIcon (NULL, IDI_APPLICATION);

	RegisterClassEx(&wc);

	hwndMain = CreateMainWnd(0);
	ShowWindow(hwndMain, iShowCmd);

	hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR1));

	while(GetMessage(&msg, NULL,0,0))
	{
		if(!TranslateAccelerator(hwndMain, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}


	return 0;
}